"""
独立的止损服务模块

职责：
- 统一的止损检查逻辑
- 支持回测、实盘、模拟盘
- 与执行器解耦，易于测试和扩展
"""

import logging
from abc import ABC, abstractmethod
from typing import Dict, List, Tuple, Optional
from datetime import datetime

logger = logging.getLogger(__name__)


class IStopLossService(ABC):
    """止损服务接口（抽象基类）"""
    
    @abstractmethod
    def check_all_positions(self, 
                           positions: Dict,
                           current_prices: Dict[str, float],
                           current_date: str,
                           stock_data_dict: Optional[Dict] = None) -> List[Tuple[str, str]]:
        """
        检查所有持仓是否触发止损
        
        Args:
            positions: 持仓字典 {stock: position_info}
            current_prices: 当前价格字典 {stock: price}
            current_date: 当前日期 (YYYYMMDD格式)
            stock_data_dict: 股票历史数据（可选，用于更新ATR）
        
        Returns:
            需要止损的股票列表 [(stock, reason), ...]
        """
        pass


class StandardStopLossService(IStopLossService):
    """
    标准止损服务实现
    
    特点：
    - 使用 PositionInfo 集成的止损逻辑
    - 自动处理 T+1 规则
    - 支持多种止损策略（fixed/atr/atr_trailing）
    """
    
    def __init__(self):
        """初始化止损服务"""
        from config_loader import STOP_LOSS_CONFIG
        self.config = STOP_LOSS_CONFIG
        self.enabled = self.config.get('enabled', True)
        logger.info(f"止损服务已初始化: enabled={self.enabled}, strategy={self.config.get('strategy', 'N/A')}")
    
    def check_all_positions(self,
                           positions: Dict,
                           current_prices: Dict[str, float],
                           current_date: str,
                           stock_data_dict: Optional[Dict] = None) -> List[Tuple[str, str]]:
        """
        检查所有持仓是否触发止损
        
        实现逻辑：
        1. 更新所有持仓的止损状态（最高价、ATR）
        2. 逐个检查是否触发止损
        3. 返回需要止损的股票列表
        """
        if not self.enabled:
            return []
        
        stop_loss_list = []
        
        for stock, position_info in positions.items():
            # 跳过没有 PositionInfo 的持仓（兼容性处理）
            if not hasattr(position_info, 'should_stop_loss'):
                continue
            
            # 获取当前价格
            current_price = current_prices.get(stock, 0)
            if current_price <= 0:
                logger.debug(f"{stock} 价格无效，跳过止损检查")
                continue
            
            try:
                # 更新止损状态（最高价、ATR等）
                stock_data = stock_data_dict.get(stock) if stock_data_dict else None
                position_info.update_stop_loss(current_price, stock_data)
                
                # 检查是否触发止损
                should_stop, reason = position_info.should_stop_loss(
                    current_price=current_price,
                    current_date=current_date
                )
                
                if should_stop:
                    logger.warning(f"🛑 {stock} 触发止损: {reason}")
                    stop_loss_list.append((stock, reason))
                    
            except Exception as e:
                logger.error(f"{stock} 止损检查异常: {str(e)}", exc_info=True)
        
        return stop_loss_list
    
    def is_enabled(self) -> bool:
        """检查止损是否启用"""
        return self.enabled
    
    def get_config(self) -> Dict:
        """获取止损配置"""
        return self.config.copy()


def create_stop_loss_service() -> IStopLossService:
    """
    工厂函数：创建止损服务实例
    
    Returns:
        止损服务实例
    """
    return StandardStopLossService()


# 为了向后兼容，提供一个全局单例（可选）
_global_stop_loss_service: Optional[IStopLossService] = None


def get_stop_loss_service() -> IStopLossService:
    """
    获取全局止损服务单例
    
    Returns:
        止损服务实例
    """
    global _global_stop_loss_service
    if _global_stop_loss_service is None:
        _global_stop_loss_service = create_stop_loss_service()
    return _global_stop_loss_service


if __name__ == '__main__':
    # 测试代码
    logging.basicConfig(level=logging.INFO)
    
    print("=" * 60)
    print("止损服务测试")
    print("=" * 60)
    
    service = create_stop_loss_service()
    print(f"服务已创建: {service}")
    print(f"是否启用: {service.is_enabled()}")
    print(f"配置信息: {service.get_config()}")
    
    print("\n测试完成 ✅")

